package org.example;

import org.example.domain.CuttingPlanSolution;
import org.example.domain.CuttingSpot;
import org.example.domain.RectangularPiece;
import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.api.solver.SolverFactory;
import javax.swing.SwingUtilities;

import java.util.ArrayList;
import java.util.List;

import org.example.visualization.CuttingVisualizer;

public class CuttingOptimizer {
    public static void main(String[] args) {
        // 创建求解器
        SolverFactory<CuttingPlanSolution> solverFactory = SolverFactory.createFromXmlResource(
                "solverConfig.xml");
        Solver<CuttingPlanSolution> solver = solverFactory.buildSolver();

        // 创建初始解
        CuttingPlanSolution unsolvedSolution = createInitialSolution();
        
        // 求解
        CuttingPlanSolution solvedSolution = solver.solve(unsolvedSolution);
        
        // 输出结果
        printSolution(solvedSolution);
        
        // 可视化结果
        visualizeSolution(solvedSolution);
    }
    
    private static CuttingPlanSolution createInitialSolution() {
        CuttingPlanSolution solution = new CuttingPlanSolution();

        // 创建板料 - 两种不同尺寸的板料
//        List<RectangularPiece> stockPieces = new ArrayList<>();
//        stockPieces.add(new RectangularPiece(1L, 100, 80, true, 1)); // 100x80的板料
//        stockPieces.add(new RectangularPiece(2L, 120, 60, true, 1)); // 120x60的板料
//        solution.setStockPieces(stockPieces);
//
//        // 创建需要切割的零件
//        List<RectangularPiece> demandPieces = new ArrayList<>();
//        // 添加不同尺寸的零件，每种都需要多个
//        demandPieces.add(new RectangularPiece(3L, 30, 20, false, 3)); // 30x20的零件，需要3个
//        demandPieces.add(new RectangularPiece(4L, 40, 30, false, 2)); // 40x30的零件，需要2个
//        demandPieces.add(new RectangularPiece(5L, 50, 40, false, 2)); // 50x40的零件，需要2个
//        solution.setDemandPieces(demandPieces);

        // 创建板料 - 两种不同尺寸的板料
        List<RectangularPiece> stockPieces = new ArrayList<>();
        stockPieces.add(new RectangularPiece(1L, 2955, 1220, true, 1)); // 100x80的板料
        solution.setStockPieces(stockPieces);

        // 创建需要切割的零件
        List<RectangularPiece> demandPieces = new ArrayList<>();
        // 添加不同尺寸的零件，每种都需要多个
        demandPieces.add(new RectangularPiece(3L, 850, 170, false, 15)); // 30x20的零件，需要3个
        demandPieces.add(new RectangularPiece(4L, 185, 495, false, 10)); // 40x30的零件，需要2个
        demandPieces.add(new RectangularPiece(5L, 280, 155, false, 6)); // 50x40的零件，需要2个
        demandPieces.add(new RectangularPiece(7L, 190, 75, false, 4)); // 50x40的零件，需要2个
        demandPieces.add(new RectangularPiece(8L, 130, 75, false, 2)); // 50x40的零件，需要2个
        solution.setDemandPieces(demandPieces);

        // 创建切割位置
        List<CuttingSpot> spots = new ArrayList<>();
        // 为每个需求的零件创建对应数量的切割位置
        for (RectangularPiece piece : demandPieces) {
            for (int i = 0; i < piece.getDemand(); i++) {
                spots.add(new CuttingSpot(piece));
            }
        }
        solution.setCuttingSpots(spots);

        return solution;
    }

    private static void printSolution(CuttingPlanSolution solution) {
        System.out.println("\n切割方案结果:");
        System.out.println("总分: " + solution.getScore());
        
        // 按板料分组打印切割位置
        solution.getStockPieces().forEach(stock -> {
            System.out.println("\n板料 " + stock.getId() + " (" + stock.getWidth() + "x" + stock.getHeight() + "):");
            solution.getCuttingSpots().stream()
                    .filter(spot -> stock.equals(spot.getStock()))
                    .forEach(spot -> System.out.printf("  零件 %d (%dx%d) 位置: (%d, %d)\n",
                            spot.getPiece().getId(),
                            spot.getPiece().getWidth(),
                            spot.getPiece().getHeight(),
                            spot.getX(),
                            spot.getY()));
        });
    }

    private static void visualizeSolution(CuttingPlanSolution solution) {
        // 创建并显示可视化窗口
        SwingUtilities.invokeLater(() -> {
            CuttingVisualizer visualizer = new CuttingVisualizer(solution);
            visualizer.setVisible(true);
        });
    }
} 